#pragma once

#include "comm/znx_buf.h"
#include "comm/znx_string.h"


// read a line of data in reentrant state machine.
typedef struct {
    int             state;
    znx_str_t       line;
    size_t          max_line_size;
} znx_http_readline_sm_t;


static inline void
znx_http_readline_sm_reset(znx_http_readline_sm_t *readline_sm)
{
    readline_sm->state = 0;
    ZNX_STR_SET_NULL(&readline_sm->line);
}


znx_result_t znx_http_readline(znx_http_readline_sm_t *readline_sm, znx_buf_t *buf);

static inline znx_bool_t
znx_http_empty_line(znx_http_readline_sm_t *readline_sm)
{
    if (readline_sm->line.len != 2) {
        return ZNX_FALSE;
    }

    return znx_strncmp(readline_sm->line.data, "\r\n", 2) == 0;
}


// [size]\r\n[data]\r\n
typedef enum {
    SW_CHUNK_PRESTART = 0,
    SW_CHUNK_START,
    SW_CHUNK_SIZE,
    SW_CHUNK_DATA,
    SW_CHUNK_AFTER_DATA_CRCF
} znx_http_chunk_state_t;


typedef struct {
    size_t                  size;
    size_t                  remain;
    znx_http_chunk_state_t  state;
} znx_http_chunk_sm_t;


static inline void
znx_http_chunk_sm_reset(znx_http_chunk_sm_t *sm)
{
    sm->size = 0;
    sm->remain = 0;
    sm->state = SW_CHUNK_PRESTART;
}

znx_result_t znx_http_chunk_size_parse(znx_http_chunk_sm_t *sm, znx_str_t *line);
